package DetectarLineas;

import java.awt.Color;
import java.awt.image.BufferedImage;

/**
 *
 * @author Joaquín Ortiz Díaz y Francisco Montero Perez
 */
public class Paso2 {

    public BufferedImage aplica_paso2(BufferedImage a){

        int width = a.getWidth();
        int height = a.getHeight();

        BufferedImage ejemplo = new BufferedImage(width, height, a.getType());

        int w=0;
        //calculaW se ha implementado siguiendo la referencia [13]
        int listaW[] = calculaW(a);

        for(int k=0; k<listaW.length; k++){
            if((listaW[k]!= -1 && (listaW[k]-k)>1)){
               w=listaW[k]-k;
               
        for(int i=0;i<width;i++){
            for(int j=0; j<height;j++){

                if((SC(3,i,j,a,w) > SL(3,i,j,a,w))&& (SC(3,i,j,a,w)>SR(3,i,j,a,w))){
                    int rojo=2*SC(1,i,j,a,w) - SL(1,i,j,a,w) - SR(1,i,j,a,w);
                    int verde=2*SC(2,i,j,a,w) - SL(2,i,j,a,w) - SR(2,i,j,a,w);
                    int azul=2*SC(3,i,j,a,w) - SL(3,i,j,a,w) - SR(3,i,j,a,w);
                   

                    if(rojo>255)
                        rojo=255;

                    if(azul>255)
                        azul=255;

                    if(verde>255)
                        verde=255;

                    if(rojo<0)
                        rojo=0;

                    if(azul<0)
                        azul=0;

                    if(verde<0)
                        verde=0;


                    ejemplo.setRGB(i, j, (new Color(rojo,verde,azul)).getRGB());

                }else
                    ejemplo.setRGB(i, j, (new Color(0,0,0)).getRGB());
                   
            }
          }
        }
       }
        return ejemplo;
   
   }
    public int SL(int k, int i, int j, BufferedImage a,int w){
        int suma=0;
        int color=0;
        for(int l=(j-3*w/2); l<=(j-w/2-1);l++){
            if(l>=0 && l<a.getHeight()){
                int pixel = a.getRGB(i, l);
                if(k==1){
                    color=(pixel & 0x00ff0000) >> 16;
                    suma=suma+color;
                }else if (k==2){
                    color=(pixel & 0x0000ff00) >> 8;
                    suma=suma+color;
                }else{
                    color=(pixel & 0x000000ff) >> 0;
                    suma=suma+color;
                }
            }
        }
        return suma;
    }

    
    public int SC(int k, int i, int j, BufferedImage a,int w){
        int suma=0;
        int color=0;
        for(int l=(j-w/2); l<=(j+w/2);l++){
            if(l>=0 && l<a.getHeight()){
                int pixel = a.getRGB(i, l);
                if(k==1){
                    color=(pixel & 0x00ff0000) >> 16;
                    suma=suma+color;
                }else if (k==2){
                    color=(pixel & 0x0000ff00) >> 8;
                    suma=suma+color;
                }else{
                    color=(pixel & 0x000000ff) >> 0;
                    suma=suma+color;
                }
            }
        }
        return suma;
    }
    public int SR(int k, int i, int j, BufferedImage a,int w){
        int suma=0;
        int color=0;
        for(int l=(j+w/2+1); l<=(j+(3*w/2));l++){
            if(l>=0 && l<a.getHeight()){
                int pixel = a.getRGB(i,l);
                if(k==1){
                    color=(pixel & 0x00ff0000) >> 16;
                    suma=suma+color;
                }else if (k==2){
                    color=(pixel & 0x0000ff00) >> 8;
                    suma=suma+color;
                }else{
                    color=(pixel & 0x000000ff) >> 0;
                    suma=suma+color;
                }
            }
        }
        return suma;
    }

public int[] calculaW (BufferedImage a){
        int anc = a.getWidth();
        int alt = a.getHeight();
        double varianzas[] = new double[anc];
        int w[] = new int[anc];
        double sumk=0;
        double sumi=0;
        int pix;
        double saltos[]= new double [anc]; //fluctuaciones en varianzas[]
        int startx=0;
        int endx=0;
        double firsty=0;
        double lasty=0;
        double topy =0;
        double sel[] = new double [anc];
        int start_sel[] = new int [anc];//start de cada scratch
        int end_sel[] = new int [anc];//end de cada scratch
        int cont_sel = 0;//numero de posibles scratches
        double o_sel =0;//sel media
        double u_sel =0;//desv. tipica de sel

        for(int k=0; k<anc; k++){
             for(int j=0; j<alt; j++){
                 pix = a.getRGB(k,j);
                 sumk = sumk + (pix & 0x000000ff);
             }
             sumk = sumk/alt;
            for(int i=0; i<alt; i++){
                pix = a.getRGB(k,i);
                sumi = sumi + (Math.pow(((pix & 0x000000ff) >> 0) - sumk, 2));
                sumi = sumi/alt;

            }
             varianzas[k] = sumi;

        }
        double flucMedia = 0;
        double fluctuacion = 0;
             for(int j=0; j<anc-1; j++){
              flucMedia = flucMedia + Math.abs(varianzas[j+1] - varianzas[j]);
             }
              fluctuacion = flucMedia/anc;
              
        for(int j=0; j<anc; j++){
             saltos[j] = -1;
             sel[j] = -1 ;
             w[j] = -1;
         }
        for(int j=0; j<anc-1; j++){
            if(Math.abs(varianzas[j+1]-varianzas[j])>fluctuacion)
                saltos[j]= 0;
        }

        boolean entre = false;

        for(int i=0;i<anc-1;i++){
            if (saltos[i]==0 && !entre){
                startx=i;
                start_sel[cont_sel]=i;
                firsty=varianzas[i+1];
                entre = true;
            }

            if(entre && (topy < varianzas[i]))
                topy = varianzas[i];

            if(saltos[i]!=0 && entre){
                endx = i;
                lasty = varianzas[i-1];
                entre = false;
                sel[cont_sel]=Math.abs((endx-startx)/(Math.max(firsty, lasty))-topy);
                
                end_sel[cont_sel]=i;
                cont_sel++;
            }

        }

            for(int i=0;i<cont_sel;i++){
                o_sel = o_sel + sel[i];
            }
            o_sel = o_sel/cont_sel;

            for(int i=0;i<cont_sel;i++){
                 u_sel += Math.pow(sel[i] - o_sel, 2);
            }
           u_sel = Math.sqrt(u_sel/cont_sel);

           for(int i=0;i<cont_sel;i++){
              if (Math.abs(sel[i] - o_sel) > u_sel){
               w[start_sel[i]] = end_sel[i];

             }

           }
           
        return w;

    }

}
